﻿/*
* Copyright (C) Microsoft. All rights reserved.  
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License.  You may obtain a copy 
* of the License at http://www.apache.org/licenses/LICENSE-2.0  
* 
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
* WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
* MERCHANTABLITY OR NON-INFRINGEMENT. 
*
* See the Apache License, Version 2.0 for specific language governing 
* permissions and limitations under the License.
*
*/

//
// MainPage.xaml.cpp
// Implementation of the MainPage class.
//

#include "pch.h"
#include "MainPage.xaml.h"
#include <ese_wrapper.h>
#include "StudentInfoItem.h"

using namespace ClassRoom;

using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;

namespace s = test_wrappers::storage;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

MainPage::MainPage()
{
    InitializeComponent();
    func();
}

/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.  The Parameter
/// property is typically used to configure the page.</param>
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    (void) e;   // Unused parameter
    InitializeDB();
}

void ClassRoom::MainPage::InitializeDB()
{
    Windows::Storage::StorageFolder^ appDataFolder = Windows::Storage::ApplicationData::Current->LocalFolder;

    std::wstring workingFolderName = std::wstring( appDataFolder->Path->Data(), appDataFolder->Path->Length() ) + L"\\";
    std::wstring dbFileName = workingFolderName + L"classroom.db";

    std::shared_ptr<s::db_jet_engine> se = s::createEngine();
    se->createInstance(workingFolderName);
    se->beginSession();
    se->openDatabase(dbFileName);

    _dbEngine = se;

    _studentTable.Initialize(_dbEngine);
}

void ClassRoom::MainPage::OnSaveClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    _studentTable.InsertOrUpdate(
        _wtoi(_Id->Text->Data()),
        _FirstName->Text->Data(),
        _wtoi(_MonthOfBirth->Text->Data()),
        _wtoi(_DayOfBirth->Text->Data()),
        _wtoi(_YearOfBirth->Text->Data()),
        _Hobbies->Text->Data(),
        _wtoi(_Score->Text->Data())
        );
}

void ClassRoom::MainPage::RefreshList(const std::vector<StudentRecord>& records)
{
    InfoList->Items->Clear();
    for (auto& record : records)
    {
        unsigned int id = record.id;
        String^ name = ref new String(record.name.c_str(), static_cast<unsigned int>(record.name.length()));
        unsigned int mm = record.mm;
        unsigned int dd = record.dd;
        unsigned int yy = record.yy;
        String^ hobbies = ref new String(record.hobbies.c_str(), static_cast<unsigned int>(record.hobbies.length()));
        unsigned int score = record.score;

        InfoList->Items->Append((ref new StudentInfoItem(id, name, mm, dd, yy, hobbies, score))->UIElement);
    }
}

void ClassRoom::MainPage::OnFindByIdClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    std::vector<StudentRecord> records;
    _studentTable.ReadById(
        _wtoi(_FindId->Text->Data()),
        records);
    RefreshList(records);
}

void ClassRoom::MainPage::OnDeleteByIdClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    _studentTable.DeleteById(_wtoi(_DeleteId->Text->Data()));
}

void ClassRoom::MainPage::OnFindByYearClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    std::vector<StudentRecord> records;
    _studentTable.ReadByYear(
        _wtoi(_FindYearOfBirth->Text->Data()),
        records);
    RefreshList(records);
}

void ClassRoom::MainPage::OnFindByScoreClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    std::vector<StudentRecord> records;
    _studentTable.ReadByScore(
        _wtoi(_FindScore->Text->Data()),
        records);
    RefreshList(records);
}

void ClassRoom::MainPage::OnDisplayAllClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    std::vector<StudentRecord> records;
    _studentTable.ReadAll(records);
    RefreshList(records);
}

void ClassRoom::MainPage::OnSaveBufferClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    s::binary_blob blob(_BufferData->Text->Length() * sizeof(wchar_t), _BufferData->Text->Data());
    _studentTable.UpdateImage(_wtoi(_IdForBufferData->Text->Data()), blob);
}

void ClassRoom::MainPage::OnLoadBufferClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    s::binary_blob blob;
    _studentTable.ReadImageById(_wtoi(_IdForBufferData->Text->Data()), blob);

    // add L'\0'
    unsigned int count = blob._size / sizeof(wchar_t);
    std::vector<wchar_t> buffer(count + 1);
    memcpy(&buffer[0], blob._buffer, blob._size);
    buffer[count] = L'\0';

    _BufferData->Text = ref new Platform::String(&buffer[0], count);
}

void ClassRoom::MainPage::OnAppendNoteClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    s::binary_blob newNote(_NewNote->Text->Length() * sizeof(wchar_t), _NewNote->Text->Data());
    _studentTable.AppendNote(_wtoi(_IdForNotesData->Text->Data()), newNote);
    _NewNote->Text = L"";
}

void ClassRoom::MainPage::OnLoadNotesClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    s::binary_blob allNotes;
    _studentTable.ReadNotesById(_wtoi(_IdForNotesData->Text->Data()), allNotes);

    // add L'\0'
    unsigned int count = allNotes._size / sizeof(wchar_t);
    std::vector<wchar_t> buffer(count + 1);
    memcpy(&buffer[0], allNotes._buffer, allNotes._size);
    buffer[count] = L'\0';

    _AllNotes->Text = ref new Platform::String(&buffer[0], count);
}
